51 - Lists

接下来学习List相关内容。

image-20251113111313886

1、创建项目:npx create-expo-app@latest RNList,然后使用npm run reset-project重置项目代码。

2、项目根目录创建data.json文件,找到老师的代码,添加数据

3、使用map方法,来渲染list

效果:

虽然使用ScrollViewmap方法,可以渲染list,但是不建议这样做,因为即使没有进入viewport的内容,也渲染了,对性能有影响。

52 - FlatList

react native里面有FlatList组件,可以值展示当前view的内容,性能很好。

image-20251113113733806

FlatList 核心属性

属性名称类型描述必需性
dataArray<any>用于创建列表项的数组数据源。
renderItem({ item, index, separators }) => React.Node渲染列表中每一项的函数。
keyExtractor(item: any, index: number) => string用于从数据项中提取一个唯一的字符串作为 React 元素的 key强烈推荐
ListEmptyComponentReact.Node | React.ComponentType | React.Elementdata 数组为空时,渲染该组件作为列表的占位符。
ListHeaderComponentReact.Node | React.ComponentType | React.Element渲染在列表顶部的组件。
ListFooterComponentReact.Node | React.ComponentType | React.Element渲染在列表底部的组件。
ItemSeparatorComponentReact.Node | React.ComponentType | React.Element渲染在每一项之间的分隔符组件。
refreshingboolean当前是否正在刷新(通常用于下拉刷新)。
onRefresh() => void当列表被下拉以触发刷新操作时调用的函数(下拉刷新)。
onEndReached({ distanceFromEnd: number }) => void当列表滚动到底部附近时调用的函数(常用于加载更多)。
horizontalboolean如果设置为 true,列表将水平而不是垂直渲染。
numColumnsnumber设置为大于 1 的值,可以实现多列网格布局 (Grid View)。

主要属性就是datarenderItem

虽然说理想情况是只渲染view页面的items,但是FlatList会预先渲染一些items,以达到性能优化的目的。所以刚开始的console.log(item.id)出现的数字是72,而不是7。

image-20251113114527785

keyExtractor属性

强烈建议加上这个属性,对性能优化很有帮助。

53 - Item Separator

这节课学习FlatListItemSeparatorComponent属性。作用:渲染在每一项之间的分隔符组件。

image-20251113115842556

效果:

img

54 - List Empty

这节课来学习FlatListListEmptyComponent属性。

作用:当 data 数组为空时,渲染该组件作为列表的占位符。

效果:

img

55 - List Header and Footer

这节课来学习FlatListListHeaderComponentListFooterComponent属性。分别表示渲染在列表顶部的组件和渲染在列表底部的组件。

效果:

img

img

56 - SectionList

SectionList 是 React Native 中另一个用于渲染长列表的高性能组件,它是基于 FlatList 构建的。SectionList 专门用于渲染带分组(Sectioned)的数据列表,这意味着数据会被分成不同的部分,并且每个部分通常都会有一个固定的头部标题(Header)

适用场景:

SectionList关键属性:

属性名称类型描述必需性
sectionsArray<Section>结构化的数据数组,用于生成分组列表。
renderItem({ item, section, index }) => React.Node渲染分组内每一项的函数。
renderSectionHeader({ section: Section }) => React.Node渲染每个分组头部标题的函数。
renderSectionFooter({ section: Section }) => React.Node渲染每个分组底部的组件。
ItemSeparatorComponentReact.Node | Component渲染同一分组内列表项之间的分隔符。
SectionSeparatorComponentReact.Node | Component渲染分组之间(Section Header/Footer 之间)的分隔符。
stickySectionHeadersEnabledboolean如果设置为 true,分组头部会停留在屏幕顶部(粘性头部),直到下一个头部滚动到位。

用案例说明:

1、创建数据文件grouped-data.json

2、编写组件

效果:

img

57 - Inputs and Forms

web开发中,HTML提供了很多原生的元素来捕获用户输入。但是RN核心库只提供了TextInput和Switch两个元素。

那其余组件怎么办?expo提供了一些。如果还需要别的组件,使用第三方组件库就可以。

image-20251113133022907

image-20251113133618809

 

关于RN里面的forms,我们主要学习四方面的内容。

image-20251113133252592

创建项目:npx create-expo-app@latest RNForms,然后使用npm run reset-project重置项目代码。

58 - TextInput

image-20251113133851013

这节课学习TextInput组件。TextInput 是 React Native 中处理文本输入最核心、也是最重要的组件。它允许用户输入文本,是构建几乎所有表单(如登录、注册、搜索)的基础。

核心属性:

属性名称类型描述主要用途
valuestring当前输入框中显示的文本值。通常绑定到组件的 state控制组件的关键
onChangeText(text: string) => void当文本发生变化时调用的回调函数。用于将输入同步到 state数据绑定的关键
placeholderstring当输入为空时显示的占位符文本。提示用户输入内容
placeholderTextColorColor占位符文本的颜色。美化 UI
editableboolean如果设置为 false,文本输入框将不可编辑。禁用输入
multilineboolean如果设置为 true,输入框可以输入多行文本。大段文本输入(如留言)
maxLengthnumber限制输入的最大字符数。限制输入长度
autoCorrectboolean如果设置为 false,则禁用设备提供的自动修正自动建议输入专有名词、代码或不需要修正的内容时(如用户名)
autoFocusboolean如果设置为 true,组件挂载后会自动聚焦。页面加载后立即输入

案例:

效果:

59 - TextInput Props

这节课演示了一下这些属性:placeholder、secureTextEntry、keyboardType、autoCorrect、autoCapitalize。自己试一下即可。

键盘配置属性:

属性名称类型描述适用场景
keyboardTypeenum设置虚拟键盘的类型,以匹配预期的输入数据。numeric (数字), email-address (邮箱), phone-pad (电话号码), default (默认)
secureTextEntryboolean如果设置为 true,输入的内容将被隐藏(用于密码输入)。密码输入框
autoCapitalizeenum控制输入文本的自动大写行为。none, sentences, words, characters
returnKeyTypeenum设置键盘右下角“返回”键的样式和文本。done, go, next, send
onSubmitEditing(event) => void当用户按下键盘上的“返回”/“完成”键时调用的函数。提交表单或跳转到下一个输入框

60 - Multiline TextInput

设置TextInputmultiline属性为true,即可将其变为多行输入框。

效果:

需要注意的是,在ios中,多行输入框中的文字位置是left-top;而在android中,则是left-center。为了解决这个问题,需要在多行输入框中设置样式textAlignVertical: "top"

image-20251113140838248

 

61 - Switch

Switch 组件是 React Native 中的另一个核心表单组件,它用于渲染一个布尔值输入,通常以可切换的滑块形式出现,代表“开/关”或“是/否”的状态。

image-20251113141325998

Switch 是一个受控组件 (Controlled Component),这意味着您需要使用组件的 state 来管理它的当前状态 (value),并使用 onValueChange 来响应用户的切换操作。

核心属性(Core Props)

属性名称类型描述必需性
valueboolean开关的当前状态。true 为开,false 为关。是 (作为受控组件)
onValueChange(value: boolean) => void当用户切换开关时调用的回调函数。回调参数是新的状态值。是 (用于响应用户输入)
disabledboolean如果设置为 true,开关将变灰且不可操作。

样式配置属性 (Color Props)

属性名称类型描述平台差异
trackColor{ false?: Color, true?: Color }设置开关轨道 (Track) 的颜色。通常用于显示开/关状态的背景色。跨平台,但用法稍有不同
thumbColorColor设置开关滑块 (Thumb) 的颜色。Android 和 iOS 行为不同,推荐使用。
ios_backgroundColorColor仅限 iOS。设置开关禁用时的背景颜色。仅限 iOS

案例:

效果:

最让我感到惊奇的是,我的ios26系统的玻璃效果,都出现在上面了,太牛逼了。

62 - Login Form

接下来的4节课,学习构建一个login form。这节课先把页面的结构写完:

效果:

img

63 - KeyboardAvoidingView

上节课完成了login form的基本结构,但是存在一个问题,就是聚焦到输入框时,输入键盘会挡住login form界面,当输入框比较多的时候,剩下的输入框就无法显示并且输入了。

img

此时可以在最外层元素上使用KeyboardAvoidingView组件来解决,KeyboardAvoidingView 是 React Native 提供的一个组件,其主要作用是自动调整视图的高度、内边距或底部定位,以避免虚拟键盘遮挡用户正在编辑的输入框(如 TextInput)。

核心属性

属性名称类型描述平台差异
behaviorenum定义视图如何调整以适应键盘。 这是最重要的属性。在 iOS 上表现良好,在 Android 上行为可能不一致。
keyboardVerticalOffsetnumber调整键盘出现时,视图与键盘之间的垂直偏移量用于微调组件的位置,例如留出导航栏的高度。
contentContainerStyleStyle应用于其内部内容的样式。

behavior 属性详解

描述适用平台
padding通过增加视图底部的 padding 来抬高内容,使输入框可见。推荐在 iOS 上使用。
position通过调整视图的绝对定位 (absolute position) 来抬高内容。适用于需要保持固定大小的视图。
height通过改变容器的高度来适应键盘,这种方式可能会导致不必要的重排。不常用,通常不如 paddingposition 效果好。

为了更加严重的说明问题,我们在login form的最上面加上一张图片,模拟form很长的情况。这时候还需要使用到keyboardVerticalOffset参数。

可以看到,调整到可以显示login按钮了。

64 - Form Validation

这节课学习怎么为form添加校验。

65 - Form Submission

这节课学习表单提交。定义handleSubmit函数。

因为录屏好像录不了密码输入的过程,所以下面gif里面输入密码的过程看不到,但是实际效果是OK的:

66 - Networking

在react native中,可以使用tanstatck/react-query来做网络请求,这个非常方便。但是课程上直接使用JS代码来请求。

创建项目npx create-expo-app@latest RNNetworking,运行nm run reset-project重置项目。

在根目录里面创建db.json,将jsonplaceholder.typicode.com里面的posts数据放进去,使用Json-server来做后端服务。启动服务json-server --watch ./db.json --port 4000

初始化页面:

67 - GET Requests

编写GET请求,渲染list列表:

效果:

68 - Loading State

这节课学习为接口请求添加loading效果。使用ActivityIndicator来展示Loading效果。

效果:

69 - Pull to Refresh

这节课学习下拉刷新,在下拉的时候增加页数,获取到的数据添加到数组头部。

实现下拉刷新主要依赖于 FlatList 的两个核心属性:

  1. refreshing: 一个布尔值,用于告诉 FlatList 当前是否正在刷新中,如果为true,会显示一个加载指示器的效果。
  2. onRefresh: 一个函数,当用户下拉列表时会被调用,用于触发数据加载逻辑,这个函数才是重点。

效果:

70 - POST Request

这节课来学习新增请求。用之前学习的login form的知识来写,没有什么问题。

效果:

71 - Error Handling

错误处理我会,就是加一个error状态,老师是使用这个error状态直接整个页面给替换了,我感觉不是很好,所以查了以下,可以按照下面的最佳实践来做。

场景推荐方法提示
操作失败 (非列表)Toast 消息自动消失,对用户干扰最小。
列表首次加载失败全屏错误覆盖(带重试按钮)确保用户看到错误并引导他们操作。
下拉刷新/滚动加载失败列表头部/底部展示错误(不隐藏内容)允许用户查看已加载的数据,并在局部区域提示错误。

列表首次加载失败,可以这样显示错误信息,要加一个try again的按钮,方便用户重新查看。

image-20251114155127135

下拉刷新的错误信息显示,估计是在列表顶部加一行,然后里面有错误信息,还有try again的按钮。